<template>
  <el-drawer
    ref="drawerBox"
    v-bind="$attrs"
    :visible.sync="dialogVisible"
    :wrapper-closable="true"
    :close-on-press-escape="false"
    :before-close="handleClose"
    :size="showMobilePage?'100%':'80%'"
    title="添加核销"
    append-to-body
    v-on="$listeners"
    @close="closeDialog"
    @open="openDialog"
  >
    <div class="drawer-content">
      <FilterInput
        v-if="!isOtherTab"
        v-model="filterData"
        :filter-list="filterList"
        show-search-btn
        line-feed
        class="FilterTool"
        @handelClick="queryClick"
        @queryEmpty="queryEmpty"
        @filterTagStatus="filterTagStatus" />
      <el-form v-else :inline="true" :model="otherParams" :class="{'mobile-top-filter': showMobilePage}" size="small">
        <el-form-item label="付款人名称">
          <el-input
            v-model="otherParams.clientName"
            class="width240"
            placeholder="请输入"
            clearable
            @keyup.enter.native="handleOtherEnter"/>
        </el-form-item>
        <el-form-item label="收入金额">
          <el-input
            v-only-number="{max: 999999999999 ,min: -999999999999, precision: 3, enableNull: true}"
            v-model="otherParams.incomeAmount"
            class="width120"
            type="number"
            oninput="if(value>999999999999)value=999999999999"
            placeholder="精确到小数点"
            clearable
            @keyup.enter.native="handleOtherEnter"/>
        </el-form-item>
        <el-form-item label="到账日期" style="margin-right: 12px !important">
          <el-date-picker
            v-model="otherParams.arrivalTime"
            :clearable="false"
            :editable="false"
            class="width120"
            type="date"
            size="small"
            value-format="timestamp"
            format="yyyy/MM/dd"
            placeholder="选择日期" />
        </el-form-item>
        <el-form-item>
          <template v-if="showMobilePage">
            <el-button :disabled="searchOtherDisabled" type="primary" @click="handleOtherSearch">搜索</el-button>
            <el-button @click="resetOtherSearch">重置</el-button>
          </template>
          <template v-else>
            <el-button :disabled="searchOtherDisabled" type="primary" style="width: 40px; height: 32px; padding: 0" @click="handleOtherSearch">
              <img :src="searchIcon" width="16px" height="16px" alt="" style="filter: brightness(999);">
            </el-button>
            <div style="display: inline-block; cursor: pointer; margin-left: 10px;" @click="resetOtherSearch">
              <el-tooltip :open-delay="500" content="重置筛选" placement="top">
                <img :src="resetFilterIcon" width="16px" height="16px" alt="">
              </el-tooltip>
            </div>
          </template>
        </el-form-item>
      </el-form>
      <el-tabs v-model="curTabName" type="card" class="detail-tabs-container" style="margin: 8px 0" @tab-click="checkSelectTab">
        <el-tab-pane label="可见流水" name="all"/>
        <el-tab-pane name="other">
          <span slot="label">不可见流水</span>
        </el-tab-pane>
      </el-tabs>
      <div class="table-box">
        <div v-loading="listLoading" class="table-list">
          <el-table
            v-loading="listLoading"
            v-if="(isAllTab && list.items.length) || (isOtherTab && otherList.items.length)"
            ref="financeTable"
            :data="isAllTab ? list.items : otherList.items"
            :height="setTableHeight"
            class="fb-table"
            element-loading-text="加载中..."
            empty-text="暂无数据"
            fit
            hightlight-current-row
          >
            <el-table-column align="left" label="到账日期" min-width="110">
              <template slot-scope="scope">
                <div>{{ scope.row.arrivalTime | standardFormat('YYYY/MM/DD') }}</div>
              </template>
            </el-table-column>
            <el-table-column align="left" label="付款人名称" width="140">
              <template slot-scope="scope">
                <ToolTip :content="scope.row.payName" />
              </template>
            </el-table-column>
            <el-table-column align="right" label="收入金额(元)" width="140">
              <template slot-scope="scope">
                <PriceColumn :real-val="scope.row.incomeAmount" :price="returnFen(scope.row.incomeAmount)" />
              </template>
            </el-table-column>
            <el-table-column align="right" label="可核销金额(元)" width="140">
              <template slot-scope="scope">
                <PriceColumn :real-val="scope.row.unWriteOffAmount" :price="returnFen(scope.row.unWriteOffAmount)" />
              </template>
            </el-table-column>
            <el-table-column align="left" label="该订单核销" width="100">
              <template slot-scope="scope">
                <ToolTip :content="returnFen(scope.row.enterAccAmount)" />
              </template>
            </el-table-column>
            <el-table-column align="left" label="付款账号" width="140">
              <template slot-scope="scope">
                <SecretText :log-text="`财务流水${scope.row.flowNumber}的付款账号`" :origin-text="scope.row.payNumber" />
              </template>
            </el-table-column>
            <el-table-column align="left" label="交易单号" width="140">
              <template slot-scope="scope">
                <ToolTip :content="scope.row.transactionNumber" />
              </template>
            </el-table-column>
            <el-table-column align="left" label="类型" width="80">
              <template slot-scope="scope">{{ scope.row.flowType | flowTypeFilter }}</template>
            </el-table-column>
            <el-table-column align="left" label="流水单号" width="170">
              <template slot-scope="scope">
                <ToolTip :content="scope.row.flowNumber" />
              </template>
            </el-table-column>
            <el-table-column align="left" label="核销状态" width="110">
              <template slot-scope="scope">{{ scope.row.verificationState | setVerificationState }}</template>
            </el-table-column>
            <el-table-column align="left" label="备注" width="110">
              <template slot-scope="scope">
                <ToolTip :content="scope.row.remark" />
              </template>
            </el-table-column>
            <el-table-column :fixed="showMobilePage ? false : 'right'" align="center" label="核销金额(元)" width="120">
              <template slot-scope="scope">
                <div class="table-inner-input">
                  <!-- disabled：如果总可核销金额为负，那么订单的待核销金额如果是正的就不能填写， 如果总可核销金额为正的，则待核销金额如果是负的就不能填写 -->
                  <!-- :disabled="(isPositive && scope.row.unWriteOffAmount <= 0) || (!isPositive && scope.row.unWriteOffAmount > 0)" -->
                  <el-input
                    v-only-number="{max: 9999999999999999 ,min: -9999999999999, precision: 2, enableNull: true}"
                    v-model="scope.row.creditAmount"
                    type="number"
                    class="credit-amount"
                    @mousewheel.native.prevent
                    @input="getAmount(scope)"
                  />
                </div>
              </template>
            </el-table-column>
            <el-table-column v-if="isShowMonth" :fixed="showMobilePage ? false : 'right'" label="业绩月份" align="center" width="130">
              <template slot="header">
                <el-tooltip effect="dark" placement="top-start">
                  <div slot="content" style="max-width: 140px;">
                    以订单最后核销的流水所设置的业绩月份为准
                  </div>
                  <div class="custom-table-header">
                    <span class="name">业绩月份</span>
                    <i class="el-icon-warning-outline" />
                  </div>
                </el-tooltip>
              </template>
              <template slot-scope="scope">
                <el-date-picker
                  v-model="scope.row.performanceMonth"
                  :clearable="false"
                  :editable="false"
                  type="month"
                  value-format="timestamp"
                  format="yyyy/MM"
                />
              </template>
            </el-table-column>
            <el-table-column align="left" width="80" fixed="right">
              <template slot="header">
                <div class="custom-table-header">
                  <span class="name">操作</span>
                </div>
              </template>
              <template slot-scope="scope">
                <el-button
                  :loading="scope.row.loading"
                  :disabled="btnLoading"
                  type="text"
                  class="to-comfirm"
                  @click="toConfirm(scope)"
                >确认核销</el-button>
              </template>
            </el-table-column>
          </el-table>
          <div v-else style="margin-bottom: 24px;text-align: center;">
            <empty-placeholder
              :text="emptyText"
              :empty-img="emptySearchImg"
              :class="{ 'showy-text': isAllTab }"
              text-color="#999"
              image-size="140px" />
            <div v-if="isAllTab" style="color: #999; font-size: 14px; margin-top: 6px">智能提示：切换至【不可见流水】可搜索无权限查看的流水噢~</div>
          </div>
        </div>
        <el-row type="flex" justify="end" class="pagination-area">
          <el-pagination
            v-if="isAllTab || isOtherTab"
            v-show="(isAllTab && list.total > 0) || (isOtherTab && otherList.total > 0)"
            :current-page="isAllTab ? list.page : otherList.page"
            :page-size="isAllTab ? list.perPage : otherList.perPage"
            :total="isAllTab ? list.total : otherList.total"
            :page-sizes="[20, 50, 100, 250, 500]"
            :layout="showMobilePage?'total, prev, next, jumper':'total, prev, pager, next, sizes, jumper'"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange" />
        </el-row>
      </div>
    </div>
  </el-drawer>
</template>

<script>
import Title from '@/components/Title';
import ClearBtn from '@/components/Common/ClearBtn';
import EmptyPlaceholder from '@/components/EmptyPlaceholder';
import chargeOff from '@/views/finance/mixins/chargeOff';
import TableAdaptive from '@/mixins/tableAdaptive';
import { verificationOptions } from '@/views/project/model/selectData';
import { setVerificationState } from '@/filters/status';
import { standardFormat } from '@/filters/date';
import { getList, writeOffFinance } from '@/api/finance';
import { paramsRangeFormat } from '@/utils/paramsFormat';
import searchIcon from '@/assets/search-resource.png';
import resetFilterIcon from '@/assets/setting/resetFilter.png';
import emptySearchImg from '@/assets/empty-search.png';
import { mapState } from 'vuex';
import axios from 'axios';

export default {
  filters: {
    setVerificationState,
    standardFormat,
    flowTypeFilter(val) {
      // 流水类型。0:普通 1:对抵
      let text = '--';
      switch (val) {
        case 0:
          text = '普通';
          break;
        case 1:
          text = '对抵';
          break;
      }
      return text;
    }
  },
  components: {
    Title,
    ClearBtn,
    EmptyPlaceholder
  },
  mixins: [chargeOff, TableAdaptive],
  props: {
    orderId: {
      type: Number,
      default: null
    },
    clientId: {
      type: Number,
      default: null
    },
    isShowMonth: {
      type: Boolean,
      default: false
    },
    orderType: {
      type: Number,
      default: null
    },
    writeOffAmount: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      searchIcon,
      emptySearchImg,
      resetFilterIcon,
      loading: false,
      dialogVisible: false,
      btnLoading: false,
      listLoading: false,
      unWriteOffAmount: 0,
      curTabName: 'all',
      cancelToken: null,
      page: 1,
      perPage: 20,
      list: {
        items: [],
        page: 1,
        perPage: 20,
        total: 0,
        isInit: true,
        totalAmount: '',
        amount: {}
      },
      otherPage: 1,
      otherPerPage: 20,
      otherList: {
        items: [],
        page: 1,
        perPage: 20,
        total: 0
      },
      isEnterSuccess: false,
      filterData: {
        clientName: ''
      },
      otherParams: {
        clientName: '',
        incomeAmount: null,
        arrivalTime: null
      },
      filterList: [
        { keyword: 'clientName', name: '付款人名称', type: 'input' },
        { keyword: 'transactionNumber', name: '交易单号', type: 'input' },
        { keyword: 'flowOrderNum', name: '流水单号', type: 'input' },
        { keyword: 'payName', name: '付款账号', type: 'input' },
        { keyword: 'remark', name: '备注', type: 'input' },
        { keyword: 'incomeAmount', name: '收入金额', type: 'inputRange' },

        { keyword: 'verificationState', name: '核销状态', type: 'select', options: verificationOptions },
        { keyword: 'flowType', name: '类型', type: 'select', labelWidth: '40px', options: [{ value: 0, label: '普通' }, { value: 1, label: '对抵' }] },
        { keyword: 'arrivalTime', name: '到账日期', type: 'rangeDate', timeType: 'daterange', format: 'yyyy/MM/dd' }
      ],
      dataOption: [{
        keyword: 'arrival',
        name: '到账日期'
      }],
      projectId: '',
      mengliOrderId: '',
      isPositive: false,
      creditAmount: null,
      clientName: '',
      otherText: '',
      rangeKeyArr: [{
        attr: 'arrivalTime',
        start: 'arrivalStartTime',
        end: 'arrivalEndTime',
        type: 'time'
      }, {
        attr: 'incomeAmount',
        start: 'incomeAmountStart',
        end: 'incomeAmountEnd',
        type: 'moneyFixed'
      }]
    };
  },
  computed: {
    ...mapState({
      'showMobilePage': state => state.app.showMobilePage
    }),
    isAllTab() {
      return this.curTabName === 'all';
    },
    isOtherTab() {
      return this.curTabName === 'other';
    },
    tableOutsideHeight() {
      return this.showMobilePage ? this.isAllTab ? 236 : 368 : 198;
    },
    searchOtherDisabled() {
      const { clientName, incomeAmount, arrivalTime } = this.otherParams;
      return !clientName || !incomeAmount || !arrivalTime;
    },
    searchTip() {
      return '同时精准搜索 "付款人名称" + "收入金额" + "到账日期"，即可查找无权限查看的流水';
    },
    emptyText() {
      if (this.isAllTab) {
        return '找不到流水，请换个关键词搜索';
      } else if (this.isOtherTab) {
        return this.otherText || this.searchTip;
      }
      return '暂无数据';
    }
  },
  watch: {
    'otherParams': {
      handler(val) {
        if (!val.clientName && !val.incomeAmount) {
          this.otherText = this.searchTip;
        }
      },
      deep: true
    }
  },
  methods: {
    fetchData(reset = false) {
      if (reset) this.page = 1;
      const params = JSON.parse(JSON.stringify(this.filterData));
      paramsRangeFormat(this.rangeKeyArr, params);
      params.projectId = this.projectId;
      this.listLoading = true;
      if (this.orderId && !(this.orderType || this.orderType === 0)) {
        params.orderId = this.orderId;
      } else {
        params.mengliOrderId = this.orderId;
      }
      if (this.cancelToken) this.cancelToken.cancel('cancel');
      const source = axios.CancelToken.source();
      this.cancelToken = source;
      getList(this.page, this.perPage, params).then(({ data }) => {
        this.list = data;
        this.ids = '';
        this.list.isInit = false;
        this.listLoading = false;
      }, result => {
        this.listLoading = false;
      }).catch(e => {
        console.error(e);
      });
    },
    handleClose() {
      this.dialogVisible = false;
      if (this.isEnterSuccess) {
        this.$emit('enterSuccess');
      }
    },
    closeDialog() {
      this.filterData = {
        clientName: ''
      };
      this.resetOtherSearch();
      this.isEnterSuccess = false;
    },
    openDialog() {
      this.curTabName = 'all';
      this.fetchData(true);
    },
    initData(data, detail) {
      const { clientName, id } = detail;
      this.unWriteOffAmount = data;
      this.clientName = clientName;
      /**
       * 如果流水的收入金额是否为正，只能核销含税金额为正的订单，且核销金额只能输入正数
       * 如果流水的收入金额是否为负或为0，只能核销含税金额为负的订单，且核销金额只能输入负数
       */
      this.isPositive = Number(this.unWriteOffAmount) > 0; // 流水的收入金额是否为正
      this.$set(this.filterData, 'clientName', clientName);
      if (!this.orderId) {
        this.projectId = id;
      }
      this.dialogVisible = true;
    },
    handleOtherEnter() {
      if (this.otherParams.clientName && this.otherParams.incomeAmount) {
        this.handleOtherSearch();
      }
    },
    handleOtherSearch() {
      this.listLoading = true;
      const params = _.cloneDeep(this.otherParams);
      params.isOther = true;
      params.arrivalStartTime = params.arrivalTime / 1000;
      params.arrivalEndTime = params.arrivalTime / 1000;
      delete params.arrivalTime;
      if (this.cancelToken) this.cancelToken.cancel('cancel');
      const source = axios.CancelToken.source();
      this.cancelToken = source;
      getList(this.otherPage, this.otherPerPage, params, source.token).then(({ data }) => {
        this.otherList = data;
        this.listLoading = false;
        this.otherText = '必须付款人名称与收入金额精准匹配到流水，请确认后再搜索';
      }, () => {
        this.listLoading = false;
      }).catch(e => {
        console.error(e);
      });
    },
    resetOtherSearch() {
      this.otherParams = {
        clientName: '',
        incomeAmount: null,
        arrivalTime: null
      };
      this.otherList = {
        items: [],
        page: 1,
        perPage: 20,
        total: 0
      };
    },
    getAmount(scope) {
      this.creditAmount = Number(scope.row.creditAmount).toFixed(2);
      const unWriteOffAmount = Math.abs(scope.row.unWriteOffAmount / 100); // 该行可核销金额
      const writeOffAmount = Math.abs(this.writeOffAmount / 100); // 该订单/流水可核销金额
      const min = writeOffAmount > unWriteOffAmount ? unWriteOffAmount : writeOffAmount;
      const max = writeOffAmount > unWriteOffAmount ? writeOffAmount : unWriteOffAmount;
      if (unWriteOffAmount === 0 || writeOffAmount === 0) {
        if (scope.row.creditAmount > 0) {
          scope.row.creditAmount = 0;
          this.creditAmount = 0;
        }
        if (scope.row.creditAmount < 0 && scope.row.creditAmount < -max) {
          scope.row.creditAmount = -max;
          this.creditAmount = -max;
        }
      } else {
        if (Number(scope.row.creditAmount) < 0) {
          if (Number(scope.row.creditAmount) < -min) {
            this.$message.warning(`该流水最小可填写核销金额为${-min}元`);
          }
          scope.row.creditAmount = Number(scope.row.creditAmount) < -min ? -min : scope.row.creditAmount;
          this.creditAmount = Number(scope.row.creditAmount) < -min ? -min : scope.row.creditAmount;
        }
        if (Number(scope.row.creditAmount) > 0) {
          if (Number(scope.row.creditAmount) > min) {
            this.$message.warning(`该流水最大可填写核销金额为${min}元`);
          }
          scope.row.creditAmount = Math.min(Number(scope.row.creditAmount), min);
          this.creditAmount = Math.min(Number(scope.row.creditAmount), min);
        }
      }
      if (scope.row.creditAmount === '') {
        return;
      }
    },
    returnFen(amount) {
      if (amount > 0 || amount < 0) {
        return amount / 100;
      } else {
        return 0;
      }
    },
    toConfirm(scope) {
      const { creditAmount } = scope.row;
      if (!creditAmount || Number(creditAmount) === 0) {
        this.$message({
          type: 'error',
          message: `请填写不为0的核销金额`
        });
        return;
      }
      let orderInfo;
      if (this.isShowMonth) {
        const performanceMonth = scope.row.performanceMonth.toString().slice(0, scope.row.performanceMonth.toString().length - 3);
        orderInfo = [{
          id: this.orderId,
          creditAmount: scope.row.creditAmount * 100,
          performanceMonth: Number(performanceMonth),
          type: this.orderType || this.orderType === 0 ? 2 : ''
        }];
      } else {
        orderInfo = [{
          id: this.$route.params.id,
          creditAmount: scope.row.creditAmount * 100,
          type: 1
        }];
      }
      this.btnLoading = true;
      scope.row.loading = true;
      writeOffFinance(scope.row.id, orderInfo).then(res => {
        const { code, data } = res;
        if (code === 200) {
          const { clientId, clientName } = this;
          if (data) {
            const { status } = data;
            // mixins引入是否可核销提示
            this.toAddPaymanPage(clientId, clientName, status);
          } else {
            this.$message({
              type: 'success',
              message: '核销成功'
            });
            this.isAllTab ? this.fetchData() : this.handleOtherEnter();
            if (!this.isEnterSuccess) this.isEnterSuccess = true;
            this.creditAmount = null;
          }
        }
      }).catch(err => {
        console.error(err);
      }).finally(() => {
        this.btnLoading = false;
        scope.row.loading = false;
      });
    },
    handleSizeChange(val) {
      if (this.curTabName === 'all') {
        this.perPage = val;
        this.fetchData(true);
      } else if (this.curTabName === 'other') {
        this.otherPerPage = val;
        this.handleOtherSearch();
      }
    },
    handleCurrentChange(toPage) {
      if (this.curTabName === 'all') {
        this.page = toPage;
        this.fetchData();
      } else if (this.curTabName === 'other') {
        this.otherPage = toPage;
        this.handleOtherSearch();
      }
    },
    // 切换列表tab
    checkSelectTab() {
      this.isAllTab ? this.fetchData() : this.handleOtherEnter();
    },
    queryClick() {
      this.fetchData(true);
    },
    queryEmpty() {
      this.filterData = {
        clientName: ''
      };
      this.fetchData(true);
    }
  }
};
</script>
<style lang="scss" scoped>
::v-deep .el-drawer__header {
  height: 48px;
  padding: 0 12px 0 24px;
  margin: 0;
  box-shadow: 2px 4px 5px 0 rgba(221,225,234,0.3);
  display: flex;
  align-items: center;
  > span {
    font-size: 16px;
    color: #333;
  }
  ::v-deep .el-tabs__nav-wrap::after {
    height: 0 !important;
  }
}
.drawer-content {
  padding: 22px 24px 0;
  overflow-y: auto;
  &::v-deep {
    .el-form {
      height: 32px;
    }
    .el-form-item {
      margin-bottom: 0;
      margin-right: 28px;
    }
  }
  .table-list {
    &::v-deep {
      .el-table__header {
        .el-checkbox__inner {
          position: relative;
          left: -2px;
        }
      }
    }
    border-radius: 10px;
    .el-row {
      padding: 0;
    }
  }
  .detail-tabs-container {
    &::v-deep {
      .el-tabs__header  {
        margin-bottom: 0 !important;
        border-bottom: 1px solid #ddd;
        .el-tabs__nav {
          border: none !important;
        }
        .el-tabs__item {
          padding: 0 12px !important;
          height: 32px !important;
          line-height: 32px !important;
          margin-right: 8px;
          border: 1px solid #ddd;
          border-radius: 4px 4px 0px 0px;
          color: #333;
          background: #f7f8fa;
          font-size: 16px;
          &:last-child {
            margin-right: 0px;
          }
          &.is-active {
            border-bottom-color: #FFFFFF !important;
            font-weight: bold;
            background: #fff;
            color: #406eff;
          }
        }
      }
    }
  }
  .to-comfirm {
    &.is-disabled {
      background: #F5F7FA;
      color: #C0C4CC;
    }
  }
  .table-inner-input {
    &::v-deep {
      .el-input__inner {
        height: 28px;
      }
    }
  }
  .table-box {
    &::v-deep {
      .el-date-editor.el-input {
        input {
          width: 100px;
          height: 24px;
          padding-right: 12px;
          border: 1px solid #e4e4e4;
        }
        .el-input__prefix {
          .el-input__icon {
            line-height: 24px !important;
          }
        }
      }
    }
    ::v-deep .el-date-editor.el-input input {
      height: 28px;
      padding-right: 5px;
    }
  }
  .showy-text {
    ::v-deep .empty-text {
      font-size: 16px;
      color: #333 !important;
      font-weight: bold;
    }
  }
}
.dialog-scroll {
  @include scrollBar($x: hidden, $y: auto);
}
.mobile-top-filter {
  height: auto !important;
  ::v-deep {
    .el-form-item__label {
      width: 82px;
    }
    .el-form-item {
      margin-right: 0;
      margin-bottom: 24px;
    }
    .el-form-item:last-child {
      margin-bottom: 0;
    }
    .el-input__inner, .el-input {
      width: 180px !important;
    }
  }
}
.custom-table-header {
  display: flex;
  align-items: center;
  .name {
    display: inline-block;
    margin-right: 5px;
  }
}
.operate-btn {
  display: inline-block;
  width: 24px;
  height: 24px;
  cursor: pointer;
  margin-left: 5px;
  @include flexStyle(center, center);
  &.active {
    background-color: #EDEEF2;
    border-radius: 4px;
  }
  .operate-icon {
    width: 16px;
    height: 16px;
  }
}
.width240 {
  width: 240px;
  &::v-deep {
    .el-input__inner {
      width: 240px;
    }
  }
}
.width120 {
  width: 120px;
  &::v-deep {
    .el-input__inner {
      width: 120px;
      padding-right: 8px;
    }
  }
}
</style>
<style lang="scss">
@import '@/styles/placeholder.scss';
.el-message-box--center.charge-message-cancel .el-message-box__btns {
  @extend %el-message-box--center-el-message-box__btns !optional;
}
</style>
